The present disclosure relates generally to integrated circuits (ICs). More particularly, the present disclosure relates to efficiently sharing resources of the ICs, such as a field programmable gate array (FPGA), while preventing a pipelined circuit from stalling and experiencing an unnecessary reduction in throughput.
This section is intended to introduce the reader to various aspects of art that may be related to various aspects of the present invention, which are described and/or claimed below. This discussion is believed to be helpful in providing the reader with background information to facilitate a better understanding of the various aspects of the present invention. Accordingly, it should be understood that these statements are to be read in this light, and not as admissions of prior art.
Integrated circuits (ICs) take a variety of forms. For instance, field programmable gate arrays (FPGAs) are integrated circuits that are intended as relatively general-purpose devices. FPGAs may include logic that may be programmed (e.g., configured) after manufacturing to provide any desired functionality that the FPGA is designed to support. Thus, FPGAs contain programmable logic, or logic blocks, that may be configured to perform a variety of functions on the FPGAs as designed by a designer. Additionally, FPGAs may include input/output (I/O) logic, as well as high-speed communication circuitry. For instance, the high-speed communication circuitry may support various communication protocols and may include high-speed transceiver channels through which the FPGA may transmit serial data to and/or receive serial data from circuitry that is external to the FPGA.
In ICs, such as FPGAs, the programmable logic is typically configured using low level programming languages such as VHDL or Verilog. Unfortunately, these low level programming language may provide a low level of abstraction and, thus, may provide a development bather for programmable logic designers. Higher level programming languages, such as Open CL, have become useful for enabling more ease in programmable logic design. These higher level programming languages are used to generate code corresponding to the low level programming languages.
To reduce an amount of circuit area needed to implement a programmable logic design, resource sharing may be used, enabling functional unit resources of the programmable logic design to be utilized by a multitude of operations. Such resource sharing may be particularly useful when a high-level description of a circuit comprises loops and/or divergent paths of execution between resources that could be shared. Unfortunately, such sharing of resources may result in an unnecessary loss of throughput of the ICs. Indeed, in the case of multi-cycle operations, where it may take several clock cycles before a result of an operation (e.g., a floating point addition calculation) is available. During these clock cycles, the functional units could be used to compute more data, but a pipeline could stall without careful resource binding and arbitration.
Resource sharing of functional units historically has been handled by providing multiplexers at inputs of a functional unit that is to be shared. The multiplexing of incoming data allows several data sources to provide data for operation by a functional unit. The resulting output of the functional unit may be stored in a register for later access. This method of resource sharing has been particularly useful for single-cycle operations where a new result may be computed by the functional unit at each clock cycle. However, such resource sharing has not been effective for multi-cycle operations (e.g., floating point operations). During multi-cycle operations (e.g., floating point operations), it may take several clock cycles before a result of the operation is available. During these cycles, additional data could be fed to the same functional unit for additional computations. However, a pipeline could stall without careful consideration for resource binding and arbitration.